package com.resource.base.config.jwt;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.resource.project.entity.RespBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class JWTFilter extends GenericFilterBean{

    public final static String HEADER = "Authorization";
    public final static String PREFIX = "Bearer";
    private static final Logger log = LoggerFactory.getLogger(JWTFilter.class);
    private TokenProvider tokenProvider;

    public JWTFilter(TokenProvider tokenProvider) {
        this.tokenProvider = tokenProvider;
    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest;
        String jwt = this.resolveToken(httpServletRequest);
        if (StrUtil.isEmpty(jwt)){
            jwt = httpServletRequest.getParameter(HEADER);
        }
        String token = null;
        if (StrUtil.isNotEmpty(jwt)){
            token = jwt;
        }
        log.debug("请求路径:{}", httpServletRequest.getRequestURI());
        log.debug("请求token:{}", jwt);
        if (StrUtil.isNotEmpty(token) && this.tokenProvider.validateToken(token)) {
            try {
                //这里调用身份认证，并且将权限加了进去
                Authentication authentication = this.tokenProvider.getAuthentication(token);
                SecurityContextHolder.getContext().setAuthentication(authentication);
            } catch (AuthenticationException var10) {
                HttpServletResponse response = (HttpServletResponse)servletResponse;
                response.reset();
                response.setStatus(HttpStatus.FORBIDDEN.value());
                PrintWriter writer = response.getWriter();
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json; charset=UTF-8");
                RespBean respBean = RespBean.error(var10.getMessage());
                writer.write(JSONUtil.toJsonStr(respBean));
                writer.flush();
                writer.close();
                return;
            }
        }

        filterChain.doFilter(servletRequest, servletResponse);
    }

    private String resolveToken(HttpServletRequest request) {
        String bearerToken = request.getHeader(HEADER);
        return StrUtil.isNotEmpty(bearerToken) && bearerToken.startsWith(PREFIX) ? bearerToken.substring(7) : bearerToken;
    }
}
